﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Fusion
{
    /// <summary>  Image class, stores texture and frame information and supports drawing at specified position </summary>
    public class Sprite : Entity
    {
        #region Fields

		public Image image;
		public string Filename
		{
			get { return image.Name; }
			set { image.Name = value; }
		}

        public Rectangle frame;

		public Vector2 origin = Vector2.One * 0.0f;
		public Vector2 PixelOrigin
		{
			get
			{
				return origin * new Vector2( frame.Width, frame.Height );
			}
			set
			{
				origin.X = value.X / frame.Width;
				origin.Y = value.Y / frame.Height;
			}
		}

        public Color tint = Color.White;
        public SpriteEffects effects = SpriteEffects.None;
        public float depth = 0.5f;

		public bool visible = true;
		
        #endregion

        #region Constructors

        /// <summary> Default Constructor </summary>
        public Sprite()
        {
            name = "Image";
			image = new Image();
        }

        /// <summary> Copy Constructor </summary>
        public Sprite( Entity copy )
        {
            Copy( copy );
        }

        /// <summary> XML Element Constructor </summary>
        /// <param name="element">XML Element to construct from</param>
        public Sprite( XElement element )
        {
            ReadFrom( element );
        }

        /// <summary> Creates sprite with new image from texturename </summary>
        /// <param name="textureName">Manager reference name of the texture to use</param>
        public Sprite( string TextureName )
        {
			image = new Image( TextureName );
			frame = new Rectangle( 0, 0, image.Width, image.Height );
		}

		/// <summary> Creates new sprite using existing image </summary>
		/// <param name="img">Image to use</param>
		public Sprite( Image img )
		{
			image = img;
			frame = new Rectangle( 0, 0, image.Width, image.Height );
		}

        /// <summary> Copies the properties of the original </summary>
        /// <param name="original">Image to copy from</param>
        /// <returns>this</returns>
        public override Entity Copy( Entity original )
        {
            base.Copy( original );

            if( original is Sprite )
            {
                Sprite spr = original as Sprite;

                container = spr.container;

				image = new Image( spr.image.Name );

                frame = spr.frame;
                size = spr.size;

                origin = spr.origin;
                tint = spr.tint;
                effects = spr.effects;
                depth = spr.depth;
            }
            return this;
        }

        #endregion

        #region Methods

        /// <summary>  Draws the image using it's transform </summary>
        public override void Draw()
        {
			if( visible == false || image == null )
				return;

            // Generate destination rectangle
            Rectangle dest = new Rectangle( (int)(Position.X), (int)(Position.Y), (int)(size.X * Scale.X), (int)(size.Y * Scale.Y) );

            // Draw sprite
			Engine.spriteBatch.Draw( image.Texture, dest, frame, tint, Angle, PixelOrigin, effects, depth );
        }

        /// <summary> Sets size to frame </summary>
        public Sprite FullSize()
        {
			size.X = image.Width;
			size.Y = image.Height;
            scale = Vector2.One;
            return this;
        }

        /// <summary> Sets size to frame </summary>
        public Sprite FullScale()
        {
			scale.X = image.Width;
			scale.Y = image.Height;
            size = Vector2.One;
            return this;
        }

        /// <summary> Sets frame to indexed cel </summary>
        public Sprite SetCel( int index, int cols )
        {
            if( index < 0 )
                return this;

			frame.Width = image.Width / cols;
			frame.Height = image.Height / cols;

			frame.X = ( index % cols ) * frame.Width;
			frame.Y = ( index / cols ) * frame.Height;

            return this;
        }

        #endregion
    }
}
